// player.cpp

#include <iostream>
#include <SDL/SDL.h>

#include "config.h"
#include "player.hpp"
#include "util.hpp"

#define PLAYER_WIDTH 50;
#define PLAYER_HEIGHT 50;

// Constructor
Player::Player()
{
   // The number of lives will be 3. The player will be looking north. He will
   // have 100 bullets by default.
   lives = 3;
   bullets = 500;
   heading = 0;

   // Initialize offset (2D x/y coordinates) and the velocity or rate of
   // movement.
   box.x = 0; box.y = 0;
   xvel = 0; yvel = 0;

   // The player isn't moving or shooting by default.
   moving = false;
   shooting = false;

   skin = NULL;
}

// Destructor
Player::~Player()
{
   SDL_FreeSurface(skin);
}

// Load the things neccesary for later use.
void Player::init()
{
   const char *datadir = DATA_DIR;
   std::string path;

   // Load the player sprites (skin).
   path = std::string(DATA_DIR) + "/dot.png";

   // Start our shoot timer
   shoot_delay.start();
}

// Move the player along the screen. We do this by incrementing or decreasing
// the offset depending on the velocity. The only advantage of using a
// velocity is that the player will still move if any key keeps pressed.
void Player::update(SDL_Surface *screen)
{
   // Simple at the moment, control player movement. Later we will control the
   // screen movement etc.
   box.x += xvel;
   box.y += yvel;

   // Check that player is shooting. If so, shoot!
   check_shoot();

   SDL_BlitSurface(skin, NULL, screen, &box);
}

// Shoot (if you have enough bullets) and you didn't shoot less than 100
// miliseconds before.
void Player::check_shoot()
{
   if (shoot_delay.get_ticks() > 80 && shooting == true) {
      // You can only shoot if you have enough bullets, else, print a message
      // saying you need more bullets.
      if (bullets > 0)
         fprintf(stderr, "Shoot!\n");
      else
         fprintf(stderr, "Not enough bullets!\n");
      
      // Decrement our bullets counter and restart our shoot_delay timer.
      bullets--; shoot_delay.start();
   }
}

// Handle all player input: movement, shooting etc. in keyboard, mouse,
// joystick or any input source the user has especified.
void Player::handle_input(SDL_Event event)
{
   // Switch storing all possible input possibilities for the player.
   switch (event.type) {

      /**********/
      /** KEYS **/
      /**********/
   case SDL_KEYDOWN:
      // A key was triggered. Make another switch where we store all possible
      // keys which can be triggered. (TODO: Make keys changeable).
      switch (event.key.keysym.sym) {
         // Movement
      case SDLK_UP: yvel = -1; heading = 0; break;
      case SDLK_DOWN: yvel = 1; heading = 2; break;
      case SDLK_LEFT: xvel = -1; heading = 3; break;
      case SDLK_RIGHT: xvel = 1; heading = 1; break;
         // Shooting
      case SDLK_SPACE: shooting = true; break;
      } break;

   case SDL_KEYUP:
      // The key which was triggered goes up. Stop moving or shooting
      // everything. (We really check that it is moving).
      switch (event.key.keysym.sym) {
         // Movement
      case SDLK_UP: if (yvel < 0) yvel = 0; break;
      case SDLK_DOWN: if (yvel > 0) yvel = 0; break;
      case SDLK_LEFT: if (xvel < 0) xvel = 0; break;
      case SDLK_RIGHT: if (xvel > 0) xvel = 0; break;
         // Shooting
      case SDLK_SPACE: shooting = false; break;
      } break;

      /***********/
      /** MOUSE **/
      /***********/
   case SDL_MOUSEMOTION:
      // Control mouse movement (player goes to the point where mouse is).
      printf("Mouse moved by %d,%d to (%d,%d)\n", 
             event.motion.xrel, event.motion.yrel,
             event.motion.x, event.motion.y);
      break;
   case SDL_MOUSEBUTTONDOWN:
      // Mouse button triggering (1 = left button, 2 = middle button, 3 =
      // right button).
      if (event.button.button == 1)
         shooting = true;
      break;
   case SDL_MOUSEBUTTONUP:
      // Same as before. Now we control if it goes up.
      if (event.button.button == 1)
         shooting = false;
      break;
   }
}

// Get the x and y variables (used by the badguy class).
int Player::get_x()
{return box.x;}
int Player::get_y()
{return box.y;}

int Player::get_bullets()
{return bullets;}
int Player::get_lives()
{return lives;}

bool Player::is_shooting()
{return shooting;}
